package com.itheima.advantagesup.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.itheima.advantagesup.dto.RoleDTO;
import com.itheima.advantagesup.entity.SysMenu;
import com.itheima.advantagesup.entity.SysRole;
import com.itheima.advantagesup.entity.SysRoleInfo;
import com.itheima.advantagesup.mapper.SysRoleMapper;
import com.itheima.advantagesup.service.SysRoleService;
import com.itheima.advantagesup.vo.*;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class SysRoleServiceImpl implements SysRoleService {

    private final SysRoleMapper sysRoleMapper;

    /**
     * 分页
     * @param page
     * @param limit
     * @param name
     */
    @Override
    public PageBean pageSelect(Integer page, Integer limit, String name) {
        PageHelper.startPage(page,limit);
        List<RoleVO> roleVOList = sysRoleMapper.selectList(name);
        PageInfo pageInfo = new PageInfo(roleVOList);
        List<RoleVO> roleVOList2 = pageInfo.getList();

        for (RoleVO roleVO : roleVOList2) {
            List<Integer> menuIds = sysRoleMapper.selectMenuIdByRoleId(roleVO.getId());
            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < menuIds.size(); i++) {
                sb.append(menuIds.get(i));
                if (i != menuIds.size() - 1) {
                    sb.append(",");
                }
            }
            String menuId = sb.toString();
            roleVO.setMenu_id(menuId);
            roleVO.setRole_id(roleVO.getId());

        }
        PageBean pageBean = new PageBean();
        pageBean.setData(roleVOList2);
        pageBean.setCount(pageInfo.getTotal());
        pageBean.setPageSize(limit);
        pageBean.setTotalPages(pageInfo.getPages());
        pageBean.setCurrentPage(pageInfo.getPageNum());
        return pageBean;
    }

    /**
     * 添加角色
     * @param roleDTO
     */
    @Override
    public void add(RoleDTO roleDTO) {
        //往sys_role表中添加数据
        SysRole sysRole = new SysRole();
        String roleId = UUID.randomUUID().toString();
        sysRole.setId(roleId);
        sysRole.setName(roleDTO.getName());
        sysRole.setDescription(roleDTO.getDescription());
        sysRole.setCreate_date(LocalDateTime.now());
        sysRole.setUpdate_date(LocalDateTime.now());
        sysRoleMapper.insert(sysRole);

        //往sys_role_menu表中加入数据
        List<Integer> menuids = roleDTO.getMenuids();
        sysRoleMapper.insertRoleMenu2(sysRole.getId(),menuids);
        /*for (Integer menuid : menuids) {
            sysRoleMapper.insertRoleMenu(menuid);
        }*/

    }

    /**
     * 根据id回显数据
     * @param roleId
     * @return {@link RoleInfoVO}
     */
    public RoleInfoVO rowInfo(String roleId){
        SysRoleInfo sysRoleInfo = sysRoleMapper.selectRoleInfoById(roleId);
        RoleInfoVO roleInfoVO = sysRoleInfo.transformRoleInfoVO();
        //获取角色的所有菜单信息
        List<SysMenu> sysMenuList = sysRoleMapper.selectListByRoleId(sysRoleInfo.getId());

        List<MenuVO2> sysRoleInfoList = convertVOTree(sysMenuList);

        roleInfoVO.setAuthList(sysRoleInfoList);
        return roleInfoVO;
    }

    private List<MenuVO2> convertVOTree(List<SysMenu> sysMenuList) {
        List<MenuVO2> topLayerMenus = sysMenuList.stream().filter(sysMenu -> sysMenu.getPid() == 0)
                .map(new Function<SysMenu, MenuVO2>() {
                    @Override
                    public MenuVO2 apply(SysMenu sysMenu) {
                        return sysMenu.transformMenuVO2();
                    }
                }).collect(Collectors.toList());
        //获取第一层子集
        topLayerMenus.forEach(sysMenuItem1->{
            List<MenuVO2> menus = sysMenuList.stream().filter(sysMenu -> sysMenu.getPid().equals(sysMenuItem1.getId()))
                    .map(SysMenu::transformMenuVO2).collect(Collectors.toList());
            menus.forEach(sysMenuItem2->{
                List<MenuVO2> menus2 = sysMenuList.stream().filter(sysMenu -> sysMenu.getPid().equals(sysMenuItem2.getId()))
                        .map(SysMenu::transformMenuVO2).collect(Collectors.toList());
                sysMenuItem2.setChildren(menus2);
            });
            sysMenuItem1.setChildren(menus);
        });
        //获取第二层子集

        return topLayerMenus;
    }


    //-----------------------------------------------------------

    /*@Override
    public RoleInfoVO rowInfo(String roleId) {
        //RoleInfoVO roleInfoVO = new RoleInfoVO();
        SysRole sysRole = sysRoleMapper.selectRoleById(roleId);
        RoleInfoVO roleInfoVO = sysRole.transformRoleInfoVO();
        List<Integer> menuIds = sysRoleMapper.selectMenuIDsByRoleID(roleId);
        //查询角色对应的菜单(功能)
        //menuIds.get(0) 拿到父节点
        List<SysMenu> sysMenuList = sysRoleMapper.getAllDataByPId(menuIds.get(0));

        sysMenuList.forEach(sysMenu -> {
            List<SysMenu> children1 = new ArrayList<>();
            if(!CollectionUtils.isEmpty(sysMenuList)){
                children1 = sysRoleMapper.getAllDataByPId(sysMenu.getId());
                if(!CollectionUtils.isEmpty(children1)){
                    children1.forEach(sysMenu1 -> {
                        sysMenu1.setChildren(sysRoleMapper.getAllDataByPId(sysMenu1.getId()));
                    });
                }
                else {
                    children1.forEach(sysMenu2->{
                        sysMenu2.setChildren(sysRoleMapper.getAllDataByPId(null));
                    });
                }
            }
            else {
                sysMenu.setChildren(null);
                //children1 = null;
            }
            sysMenu.setChildren(children1);
        });

        *//*sysMenuList.forEach(sysMenu -> {
            List<SysMenu> children1 = sysRoleMapper.getAllDataByPId(sysMenu.getId());
            children1.forEach(sysMenu1 -> {
                sysMenu1.setChildren(sysRoleMapper.getAllDataByPId(sysMenu1.getId()));
            });
            sysMenu.setChildren(children1);
        });*//*

        roleInfoVO.setAuthList(sysMenuList);
        return roleInfoVO;

    }*/

    /**
     * 修改角色 --- 以名字为标识符
     * @param roleDTO
     */
    @Override
    public void update(RoleDTO roleDTO) {
        SysRole sysRole = new SysRole();
        //先修改sys_role数据
        sysRole.setName(roleDTO.getName());
        sysRole.setDescription(roleDTO.getDescription());
        sysRole.setUpdate_date(LocalDateTime.now());
        sysRoleMapper.update(sysRole);

        //再修改sys_role_menu表数据
        List<Integer> menuids2 = roleDTO.getMenuids();
        //删除所有数据
        sysRoleMapper.deleteRoleMenuById(sysRole.getId());
        //添加数据
        for (Integer menuid : menuids2) {
            sysRoleMapper.insertRoleMenu(roleDTO.getId(),menuid);
        }
        //sysRoleMapper.insertRoleMenu2(sysRole.getId(),menuids2);

        /*sysRoleMapper.updateMenuids(menuids2);
        for (Integer menuid : menuids2) {
            int count = countByMenuId(menuid);
            if(count>0){
                //todo 删除
                //sysRoleMapper.deleteRoleMenu(sysRole.getId(),Integer.parseInt(menuid));
                sysRoleMapper.deleteRoleMenu(sysRole.getId(),menuid);
            }
            else{
                //todo 添加
                sysRoleMapper.insertRoleMenu(sysRole.getId(),menuid);
            }
        }*/

    }

    /**
     * 根据id删除角色
     * @param id
     */
    @Override
    public void deleteById(String id) {
        //先删除sys_role
        sysRoleMapper.deleteRoleById(id);
        //根据角色id删除角色菜单表的数据
        sysRoleMapper.deleteRoleMenuById(id);
    }

    /**
     * 角色列表-全部
     * @return {@link RoleAllDataVO}
     */
    @Override
    public List<RoleAllDataVO> allData() {
        List<RoleAllDataVO> roleAllDataVOList = sysRoleMapper.selectRole();
        return roleAllDataVOList;
    }


    /**
     * 统计menuId存在的数量
     * @param menuid
     * @return int
     */
    public Integer countByMenuId(Integer menuid){
        //int menuId = Integer.parseInt(menuid);
        Integer count = sysRoleMapper.selectCountByMenuId(menuid);
        return count;
    }

}
